#include "StatusServiceImpl.h"
#include "const.h"
#include "ConfigMgr.h"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include"RedisMgr.h"
std::string get_uuid() {
    boost::uuids::uuid uid = boost::uuids::random_generator()();
    std::string uuid = to_string(uid);
    return uuid;
}




Status StatusServiceImpl::GetChatServer(ServerContext* context, const GetChatServerReq* request, GetChatServerRsp* reply)
{
    std::string prefix("status server has receive.....") ;
    std::cout << prefix << std::endl;
    const auto& server = getChatServer();
    reply->set_host(server.host);
    reply->set_port(server.port);
    reply->set_error(ErrorCodes::Success);
    reply->set_token(get_uuid());
    insertToken(request->uid(), reply->token());
    return Status::OK;

}
Status StatusServiceImpl::Login(ServerContext* context, const LoginReq* request, LoginRsp* reply)
{
    auto uid = request->uid();
    auto token = request->token();
    
    std::string uid_str=std::to_string(uid);
    std::string token_key=USERTOKENPREFIX+uid_str;
    std::string token_value = "";
    bool success = RedisMgr::GetInstance()->Get(token_key, token_value);
    if (success) {
        reply->set_error(ErrorCodes::UidInvalid);
        return Status::OK;
    }
    if (token_value != token) {
        reply->set_error(ErrorCodes::TokenInvalid);
        return Status::OK;
    }
    reply->set_error(ErrorCodes::Success);
    reply->set_uid(uid);
    reply->set_token(token);
    return Status::OK;
}
void StatusServiceImpl::insertToken(int uid, std::string token)
{
    std::string uid_str=std::to_string(uid);
    std::string token_key=USERTOKENPREFIX+uid_str;
    RedisMgr::GetInstance()->Set(token_key, token);
}
ChatServer StatusServiceImpl::getChatServer()
{
    std::lock_guard<std::mutex>lock(_server_mtx);
    auto miniServer = _servers.begin()->second;
    auto count_str = RedisMgr::GetInstance()->HGet(LOGIN_COUNT, miniServer.name);
    if (count_str.empty()) {
        miniServer.con_count=INT_MAX;
    }
    else {
        miniServer.con_count = std::stoi(count_str);
    }
    
    for (auto& server : _servers) {
        if (server.second.name == miniServer.name) {
            continue;
        }
        auto count_str = RedisMgr::GetInstance()->HGet(LOGIN_COUNT, server.second.name);
        if (count_str.empty()) {
            server.second.con_count = INT_MAX;
        }
        else {
            server.second.con_count = std::stoi(count_str);
        }
        if (server.second.con_count < miniServer.con_count) {
            miniServer = server.second;
        }
        return miniServer;
    }
}
StatusServiceImpl::StatusServiceImpl()
{
    auto& cfg = ConfigMgr::Inst();
    auto server_list = cfg["chatservers"]["Name"];
    std::vector<std::string>words;
    std::stringstream ss(server_list);
    std::string word;

    while (std::getline(ss, word, ',')) {
        words.push_back(word);
    }
    for (auto& word : words) {
        if (cfg[word]["Name"].empty()) {
            continue;
        }
        ChatServer server;
        server.port = cfg[word]["Port"];
        server.host = cfg[word]["Host"];
        server.name=cfg[word]["Name"];
        _servers[server.name] = server;
    }
}
